package com.example.service.impl;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Random;
import java.util.Set;
import java.util.stream.Collectors;
import java.net.InetAddress;
import java.net.UnknownHostException;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.DisabledException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import jakarta.servlet.http.HttpServletRequest;

import com.example.dto.ApiResponse;
import com.example.dto.ChangePasswordRequest;
import com.example.dto.JwtResponse;
import com.example.dto.LoginRequest;
import com.example.dto.RegisterRequest;
import com.example.dto.ResetPasswordRequest;
import com.example.dto.TokenResponse;
import com.example.dto.UpdateUserRequest;
import com.example.dto.UserDTO;
import com.example.entity.PasswordResetToken;
import com.example.entity.Role;
import com.example.entity.User;
import com.example.entity.UserRole;
import com.example.mapper.PasswordResetTokenMapper;
import com.example.mapper.RoleMapper;
import com.example.mapper.UserMapper;
import com.example.mapper.UserRoleMapper;
import com.example.security.JwtUtils;
import com.example.security.UserDetailsImpl;
import com.example.service.UserService;
import com.example.mapper.UserSessionMapper;
import com.example.utils.IpUtils;

@Service
public class UserServiceImpl implements UserService {

    @Override
    public Long getCurrentUserId() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null && authentication.getPrincipal() instanceof UserDetailsImpl) {
            UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
            return userDetails.getId();
        }
        return null;
    }

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private PasswordEncoder encoder;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private PasswordResetTokenMapper passwordResetTokenMapper;

    @Autowired
    private UserSessionMapper userSessionMapper;

    @Autowired
    private IpUtils ipUtils;

    @Override
    public JwtResponse authenticateUser(LoginRequest loginRequest) {
        // 先检查用户是否存在
        User user = userMapper.findByUsername(loginRequest.getUsername());
        if (user == null) {
            throw new BadCredentialsException("用户不存在");
        }

        // 检查用户是否被封禁
        if (!user.getEnabled()) {
            throw new DisabledException("账号已被封禁，请联系管理员");
        }

        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginRequest.getUsername(), loginRequest.getPassword()));

        SecurityContextHolder.getContext().setAuthentication(authentication);
        String jwt = jwtUtils.generateJwtToken(authentication);

        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        List<String> roles = userDetails.getAuthorities().stream()
                .map(item -> item.getAuthority())
                .collect(Collectors.toList());

        // 更新用户最后登录时间和IP
        if (user != null) {
            user.setLastLoginTime(LocalDateTime.now());
            String ipAddress = getIpAddress();
            user.setLastLoginIp(ipAddress);
            userMapper.updateById(user);
        }

        return new JwtResponse(jwt,
                userDetails.getId(),
                userDetails.getUsername(),
                userDetails.getEmail(),
                roles,
                userDetails.getExamNumber());
    }

    @Override
    @Transactional
    public ApiResponse<?> registerUser(RegisterRequest registerRequest) {
        if (userMapper.findByUsername(registerRequest.getUsername()) != null) {
            return ApiResponse.error("Error: Username is already taken!");
        }

        if (userMapper.findByEmail(registerRequest.getEmail()) != null) {
            return ApiResponse.error("Error: Email is already in use!");
        }

        User user = new User();
        user.setUsername(registerRequest.getUsername());
        user.setEmail(registerRequest.getEmail());
        user.setPassword(encoder.encode(registerRequest.getPassword()));
        user.setEnabled(true);
        user.setCreateTime(LocalDateTime.now());
        user.setUpdateTime(LocalDateTime.now());
        user.setAvatarUrl("users/avatars/default-avatar.png");
        
        // 设置新增的用户信息
        user.setFullName(registerRequest.getFullName());
        user.setPhoneNumber(registerRequest.getPhoneNumber());
        
        // 检查角色并处理考号格式
        boolean hasTeacherRole = registerRequest.getRoles() != null && 
            registerRequest.getRoles().stream().anyMatch(role -> role.equals("ROLE_TEACHER"));
        boolean hasAdminRole = registerRequest.getRoles() != null && 
            registerRequest.getRoles().stream().anyMatch(role -> role.equals("ROLE_ADMIN"));
        
        // 生成或处理考号
        if (hasTeacherRole) {
            // 自动为教师生成教师号：t + 随机5位数字
            user.setExamNumber(generateUniqueTeacherNumber());
        } else if (hasAdminRole) {
            // 自动为管理员生成管理号：a + 随机5位数字
            user.setExamNumber(generateUniqueAdminNumber());
        } else {
            // 普通学生使用输入的考号
            String examNumber = registerRequest.getExamNumber();
            if (examNumber != null && !examNumber.isEmpty()) {
                // 学生考号应该是纯数字
                examNumber = examNumber.replaceAll("\\D", "");
                if (examNumber.length() > 12) {
                    examNumber = examNumber.substring(0, 12);
                }
                user.setExamNumber(examNumber);
            }
        }

        userMapper.insert(user);

        // 如果用户选择了特殊角色，则使用用户选择的角色
        if (registerRequest.getRoles() != null && !registerRequest.getRoles().isEmpty()) {
            // 有指定角色，直接添加这些角色
            for (String roleName : registerRequest.getRoles()) {
                Role role = roleMapper.findByName(roleName);
                if (role != null) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(user.getId());
                    userRole.setRoleId(role.getId());
                    userRoleMapper.insert(userRole);
                }
            }
        } else {
            // 没有指定角色，默认添加ROLE_USER角色
            Role userRole = roleMapper.findByName("ROLE_USER");
            UserRole ur = new UserRole();
            ur.setUserId(user.getId());
            ur.setRoleId(userRole.getId());
            userRoleMapper.insert(ur);
        }

        return ApiResponse.success("User registered successfully!", null);
    }

    @Override
    public List<User> getAllUsers() {
        return userMapper.selectList(null);
    }

    @Override
    public List<UserDTO> getAllUsersWithRoles() {
        List<User> users = userMapper.selectList(null);
        return users.stream()
                .map(user -> {
                    List<String> roles = roleMapper.findRolesByUserId(user.getId());
                    return UserDTO.fromUser(user, roles);
                })
                .collect(Collectors.toList());
    }

    @Override
    public User getUserById(Long id) {
        return userMapper.selectById(id);
    }

    @Override
    public User getUserByUsername(String username) {
        return userMapper.findByUsername(username);
    }

    @Override
    public UserDTO getUserWithRolesById(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return null;
        }
        List<String> roles = roleMapper.findRolesByUserId(id);
        return UserDTO.fromUser(user, roles);
    }

    @Override
    @Transactional
    public ApiResponse<?> updateUser(Long id, UpdateUserRequest updateRequest) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ApiResponse.error("User not found!");
        }

        // Update user details
        user.setUsername(updateRequest.getUsername());
        user.setEmail(updateRequest.getEmail());
        user.setFullName(updateRequest.getFullName());
        user.setPhoneNumber(updateRequest.getPhoneNumber());
        user.setExamNumber(updateRequest.getExamNumber());

        // 检查用户名是否已被其他用户使用
        if (updateRequest.getUsername() != null && !updateRequest.getUsername().equals(user.getUsername())) {
            User existingUser = userMapper.findByUsername(updateRequest.getUsername());
            if (existingUser != null) {
                return ApiResponse.error("Username is already taken!");
            }
            user.setUsername(updateRequest.getUsername());
        }

        // 检查邮箱是否已被其他用户使用
        if (updateRequest.getEmail() != null && !updateRequest.getEmail().equals(user.getEmail())) {
            User existingUser = userMapper.findByEmail(updateRequest.getEmail());
            if (existingUser != null) {
                return ApiResponse.error("Email is already in use!");
            }
            user.setEmail(updateRequest.getEmail());
        }

        // 更新密码
        if (updateRequest.getPassword() != null) {
            user.setPassword(encoder.encode(updateRequest.getPassword()));
        }

        // 更新其他信息
        if (updateRequest.getFullName() != null) {
            user.setFullName(updateRequest.getFullName());
        }
        if (updateRequest.getPhoneNumber() != null) {
            user.setPhoneNumber(updateRequest.getPhoneNumber());
        }
        // 更新考号字段
        if (updateRequest.getExamNumber() != null) {
            // 获取用户角色
            List<String> roles = roleMapper.findRolesByUserId(id);
            
            // 检查用户角色并格式化考号
            String examNumber = updateRequest.getExamNumber();
            boolean hasTeacherRole = roles.stream().anyMatch(role -> role.equals("ROLE_TEACHER"));
            boolean hasAdminRole = roles.stream().anyMatch(role -> role.equals("ROLE_ADMIN"));
            
            // 根据角色自动生成或格式化考号
            if (hasTeacherRole) {
                // 如果当前考号不是以teacher开头，或者为空，则自动生成新的教师号
                if (user.getExamNumber() == null || !user.getExamNumber().startsWith("t")) {
                    examNumber = generateUniqueTeacherNumber();
                } else {
                    // 保留原教师号
                    examNumber = user.getExamNumber();
                }
            } else if (hasAdminRole) {
                // 如果当前考号不是以admin开头，或者为空，则自动生成新的管理号
                if (user.getExamNumber() == null || !user.getExamNumber().startsWith("a")) {
                    examNumber = generateUniqueAdminNumber();
                } else {
                    // 保留原管理号
                    examNumber = user.getExamNumber();
                }
            } else {
                // 普通学生使用输入的考号，确保是12位以内的纯数字
                examNumber = examNumber.replaceAll("\\D", "");
                if (examNumber.length() > 12) {
                    examNumber = examNumber.substring(0, 12);
                }
            }
            
            user.setExamNumber(examNumber);
        }

        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        return ApiResponse.success("User updated successfully!", null);
    }

    @Override
    @Transactional
    public ApiResponse<?> deleteUser(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ApiResponse.error("User not found!");
        }

        // 删除用户角色关系
        userRoleMapper.deleteByUserId(id);
        // 删除用户
        userMapper.deleteById(id);

        return ApiResponse.success("User deleted successfully!", null);
    }

    @Override
    public ApiResponse<?> changePassword(Long id, ChangePasswordRequest changePasswordRequest) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return new ApiResponse<>(false, "User not found", null);
        }

        if (!encoder.matches(changePasswordRequest.getCurrentPassword(), user.getPassword())) {
            return new ApiResponse<>(false, "Current password is incorrect", null);
        }

        user.setPassword(encoder.encode(changePasswordRequest.getNewPassword()));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        return new ApiResponse<>(true, "Password changed successfully", null);
    }

    @Override
    public ApiResponse<?> updateAvatar(Long id, String avatarUrl) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return new ApiResponse<>(false, "User not found", null);
        }

        // 确保avatarUrl是相对路径
        if (avatarUrl.startsWith("/")) {
            avatarUrl = avatarUrl.substring(1);
        }

        user.setAvatarUrl(avatarUrl);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        // 返回完整的URL路径
        String fullAvatarUrl = "/uploads/" + avatarUrl;
        return new ApiResponse<>(true, "Avatar updated successfully", fullAvatarUrl);
    }

    @Override
    public String getUserAvatarUrl(Long userId) {
        User user = userMapper.selectById(userId);
        if (user == null || user.getAvatarUrl() == null || user.getAvatarUrl().isEmpty()) {
            // 返回默认头像路径

            return "/users/avatars/default.png";
        }
        
        // 确保头像URL格式正确（以/users/avatars/开头）
        String avatarUrl = user.getAvatarUrl();
        if (!avatarUrl.startsWith("/")) {
            avatarUrl = "/" + avatarUrl;
        }
        
        if (!avatarUrl.startsWith("/users/avatars/") && avatarUrl.startsWith("/uploads/")) {
            // 转换旧格式的URL到新格式
            avatarUrl = "/users/avatars/" + avatarUrl.substring("/uploads/".length());
        }
        
        return avatarUrl;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public ApiResponse<?> updateUserRoles(Long id, List<String> roles) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ApiResponse.error("User not found!");
        }

        // 获取所有有效的角色
        List<Role> validRoles = roleMapper.findByNames(roles);
        if (validRoles.isEmpty()) {
            return ApiResponse.error("No valid roles provided!");
        }

        try {
            // 1. 先清空该用户的所有角色
            int deleteCount = userRoleMapper.deleteByUserId(id);

            // 2. 等待删除操作完成，确认删除成功
            List<UserRole> remainingRoles = userRoleMapper.findByUserId(id);
            if (!remainingRoles.isEmpty()) {
                throw new RuntimeException("Failed to delete existing roles");
            }

            // 3. 批量添加新的角色
            Set<Long> addedRoleIds = new HashSet<>(); // 用于去重
            for (Role role : validRoles) {
                if (addedRoleIds.add(role.getId())) { // 如果角色ID不存在，则添加
                    UserRole ur = new UserRole();
                    ur.setUserId(id);
                    ur.setRoleId(role.getId());
                    userRoleMapper.insert(ur);
                }
            }

            // 4. 验证最终结果
            List<UserRole> finalRoles = userRoleMapper.findByUserId(id);
            if (finalRoles.size() != addedRoleIds.size()) {
                throw new RuntimeException("Role update verification failed");
            }
            
            // 5. 根据新角色自动更新用户的考号/教师号/管理号
            boolean hasTeacherRole = roles.stream().anyMatch(role -> role.equals("ROLE_TEACHER"));
            boolean hasAdminRole = roles.stream().anyMatch(role -> role.equals("ROLE_ADMIN"));
            
            // 根据角色自动生成或格式化考号
            String examNumber = user.getExamNumber();
            boolean needsUpdate = false;
            
            if (hasTeacherRole) {
                // 如果当前考号不是以teacher开头，或者为空，则自动生成新的教师号
                if (examNumber == null || !examNumber.startsWith("t")) {
                    // 生成唯一的教师号
                    examNumber = generateUniqueTeacherNumber();
                    needsUpdate = true;
                }
            } else if (hasAdminRole) {
                // 如果当前考号不是以admin开头，或者为空，则自动生成新的管理号
                if (examNumber == null || !examNumber.startsWith("a")) {
                    // 生成唯一的管理号
                    examNumber = generateUniqueAdminNumber();
                    needsUpdate = true;
                }
            } else if (examNumber != null && (examNumber.startsWith("t") || examNumber.startsWith("a"))) {
                // 如果之前是教师或管理员，现在是学生，清空特殊考号
                examNumber = "";
                needsUpdate = true;
            }
            
            if (needsUpdate) {
                user.setExamNumber(examNumber);
                user.setUpdateTime(LocalDateTime.now());
                userMapper.updateById(user);
            }

            return ApiResponse.success("User roles updated successfully!", null);
        } catch (Exception e) {
            System.err.println("Error updating user roles: " + e.getMessage());
            e.printStackTrace();
            throw e; // 重新抛出异常，让事务回滚
        }
    }
    
    // 生成唯一的教师号
    private String generateUniqueTeacherNumber() {
        String teacherNumber;
        boolean isUnique = false;
        int maxAttempts = 10;
        int attempts = 0;
        
        do {
            // 生成教师号：t + 随机5位数字，总长度为6位
            teacherNumber = "t" + String.format("%05d", new Random().nextInt(100000));
            
            // 检查数据库中是否存在此教师号
            User existingUser = userMapper.findByExamNumber(teacherNumber);
            isUnique = (existingUser == null);
            
            attempts++;
        } while (!isUnique && attempts < maxAttempts);
        
        if (!isUnique) {
            // 如果多次尝试后仍找不到唯一的号码，使用时间戳确保唯一性
            teacherNumber = "t" + String.format("%05d", Math.abs(System.currentTimeMillis() % 100000));
        }
        
        return teacherNumber;
    }
    
    // 生成唯一的管理号
    private String generateUniqueAdminNumber() {
        String adminNumber;
        boolean isUnique = false;
        int maxAttempts = 10;
        int attempts = 0;
        
        do {
            // 生成管理号：a + 随机5位数字，总长度为6位
            adminNumber = "a" + String.format("%05d", new Random().nextInt(100000));
            
            // 检查数据库中是否存在此管理号
            User existingUser = userMapper.findByExamNumber(adminNumber);
            isUnique = (existingUser == null);
            
            attempts++;
        } while (!isUnique && attempts < maxAttempts);
        
        if (!isUnique) {
            // 如果多次尝试后仍找不到唯一的号码，使用时间戳确保唯一性
            adminNumber = "a" + String.format("%05d", Math.abs(System.currentTimeMillis() % 100000));
        }
        
        return adminNumber;
    }

    @Override
    @Transactional
    public TokenResponse generateResetToken(String username) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return null;
        }

        // 删除该用户之前未使用的所有令牌
        passwordResetTokenMapper.deleteUnusedTokensByUserId(user.getId());

        // 生成6位随机数字令牌
        String token = generateRandomToken();

        // 创建新的密码重置令牌
        PasswordResetToken resetToken = new PasswordResetToken();
        resetToken.setToken(token);
        resetToken.setUser(user);
        resetToken.setUsed(false);

        passwordResetTokenMapper.insert(resetToken);

        // 格式化过期时间为易读格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String formattedExpiryTime = resetToken.getExpiresAt().format(formatter);

        return new TokenResponse(token, username, formattedExpiryTime);
    }

    @Override
    @Transactional
    public ApiResponse<?> resetPassword(ResetPasswordRequest request) {
        // 查找用户
        User user = userMapper.findByUsername(request.getUsername());
        if (user == null) {
            return ApiResponse.error("User not found!");
        }

        // 查找令牌
        Optional<PasswordResetToken> tokenOptional = passwordResetTokenMapper.findByToken(request.getResetToken());
        if (!tokenOptional.isPresent()) {
            return ApiResponse.error("Invalid reset token!");
        }

        PasswordResetToken resetToken = tokenOptional.get();

        // 验证令牌是否属于该用户
        if (!resetToken.getUserId().equals(user.getId())) {
            return ApiResponse.error("Token does not match user!");
        }

        // 验证令牌是否已使用
        if (resetToken.isUsed()) {
            return ApiResponse.error("Token has already been used!");
        }

        // 验证令牌是否过期
        if (resetToken.isExpired()) {
            return ApiResponse.error("Token has expired!");
        }

        // 重置密码为默认密码：123456789
        user.setPassword(encoder.encode("123456789"));
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        // 标记令牌为已使用
        passwordResetTokenMapper.markAsUsed(resetToken.getToken());

        return ApiResponse.success("Password has been reset successfully!", null);
    }

    // 生成6位随机数字令牌
    private String generateRandomToken() {
        Random random = new Random();
        int number = 100000 + random.nextInt(900000); // 生成100000-999999之间的随机数
        return String.valueOf(number);
    }

    @Override
    @Transactional
    public void updateBatchUserRoles(List<Long> userIds, Set<String> roles) {
        if (userIds == null || userIds.isEmpty()) {
            throw new IllegalArgumentException("用户ID列表不能为空");
        }
        
        if (roles == null || roles.isEmpty()) {
            throw new IllegalArgumentException("角色列表不能为空");
        }
        
        // 获取有效的角色ID列表
        List<Role> validRoles = roleMapper.findByNames(roles.stream().collect(Collectors.toList()));
        if (validRoles.isEmpty()) {
            throw new IllegalArgumentException("没有找到有效的角色");
        }
        
        // 批量更新用户角色
        for (Long userId : userIds) {
            User user = userMapper.selectById(userId);
            if (user == null) {
                continue; // 跳过不存在的用户
            }
            
            try {
                // 1. 先清空该用户的所有角色
                userRoleMapper.deleteByUserId(userId);
                
                // 2. 批量添加新的角色
                for (Role role : validRoles) {
                    UserRole userRole = new UserRole();
                    userRole.setUserId(userId);
                    userRole.setRoleId(role.getId());
                    userRoleMapper.insert(userRole);
                }
                
                // 3. 根据新角色自动更新用户的考号
                boolean hasTeacherRole = roles.stream().anyMatch(role -> role.equals("ROLE_TEACHER"));
                boolean hasAdminRole = roles.stream().anyMatch(role -> role.equals("ROLE_ADMIN"));
                
                // 根据角色自动生成或格式化考号
                String examNumber = user.getExamNumber();
                boolean needsUpdate = false;
                
                if (hasTeacherRole) {
                    // 如果当前考号不是以teacher开头，或者为空，则自动生成新的教师号
                    if (examNumber == null || !examNumber.startsWith("t")) {
                        // 生成唯一的教师号
                        examNumber = generateUniqueTeacherNumber();
                        needsUpdate = true;
                    }
                } else if (hasAdminRole) {
                    // 如果当前考号不是以admin开头，或者为空，则自动生成新的管理号
                    if (examNumber == null || !examNumber.startsWith("a")) {
                        // 生成唯一的管理号
                        examNumber = generateUniqueAdminNumber();
                        needsUpdate = true;
                    }
                } else if (examNumber != null && (examNumber.startsWith("t") || examNumber.startsWith("a"))) {
                    // 如果之前是教师或管理员，现在是学生，清空特殊考号
                    examNumber = "";
                    needsUpdate = true;
                }
                
                if (needsUpdate) {
                    user.setExamNumber(examNumber);
                    user.setUpdateTime(LocalDateTime.now());
                    userMapper.updateById(user);
                }
            } catch (Exception e) {
                throw new RuntimeException("更新用户 ID: " + userId + " 的角色失败: " + e.getMessage(), e);
            }
        }
    }
    
    @Override
    @Transactional
    public void registerBatchUsers(List<RegisterRequest> users) {
        if (users == null || users.isEmpty()) {
            throw new IllegalArgumentException("用户注册请求列表不能为空");
        }
        
        // 预先检查用户名和邮箱是否已存在
        Set<String> existingUsernames = new HashSet<>();
        Set<String> existingEmails = new HashSet<>();
        
        for (RegisterRequest request : users) {
            if (userMapper.findByUsername(request.getUsername()) != null || existingUsernames.contains(request.getUsername())) {
                throw new IllegalArgumentException("用户名 '" + request.getUsername() + "' 已被使用");
            }
            
            if (userMapper.findByEmail(request.getEmail()) != null || existingEmails.contains(request.getEmail())) {
                throw new IllegalArgumentException("邮箱 '" + request.getEmail() + "' 已被使用");
            }
            
            // 添加到已检查集合中
            existingUsernames.add(request.getUsername());
            existingEmails.add(request.getEmail());
        }
        
        // 批量注册用户
        for (RegisterRequest request : users) {
            try {
                registerUser(request);
            } catch (Exception e) {
                throw new RuntimeException("注册用户 '" + request.getUsername() + "' 失败: " + e.getMessage(), e);
            }
        }
    }

    /**
     * 获取客户端IP地址
     * 使用统一的IP获取工具类
     */
    private String getIpAddress() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        return ipUtils.getClientIpAddress(request);
    }

    @Override
    @Transactional
    public ApiResponse<?> banUser(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ApiResponse.error("用户不存在");
        }
        
        // 检查是否是管理员
        List<String> roles = roleMapper.findRolesByUserId(id);
        if (roles.contains("ROLE_ADMIN")) {
            return ApiResponse.error("不能封禁管理员账号");
        }

        // 设置用户状态为禁用
        user.setEnabled(false);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        // 使该用户的所有会话失效
        userSessionMapper.invalidateAllUserSessions(id);

        return ApiResponse.success("用户已被封禁");
    }

    @Override
    @Transactional
    public ApiResponse<?> unbanUser(Long id) {
        User user = userMapper.selectById(id);
        if (user == null) {
            return ApiResponse.error("用户不存在");
        }

        // 设置用户状态为启用
        user.setEnabled(true);
        user.setUpdateTime(LocalDateTime.now());
        userMapper.updateById(user);

        return ApiResponse.success("用户已被解封");
    }

    @Override
    @Transactional
    public ApiResponse<?> batchBanUsers(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return ApiResponse.error("用户ID列表不能为空");
        }

        int successCount = 0;
        int failCount = 0;
        StringBuilder failureMessage = new StringBuilder();

        for (Long userId : userIds) {
            try {
                ApiResponse<?> response = banUser(userId);
                if (response.isSuccess()) {
                    successCount++;
                } else {
                    failCount++;
                    failureMessage.append("用户ID ").append(userId).append(": ")
                                .append(response.getMessage()).append("; ");
                }
            } catch (Exception e) {
                failCount++;
                failureMessage.append("用户ID ").append(userId).append(": ")
                            .append(e.getMessage()).append("; ");
            }
        }

        if (failCount == 0) {
            return ApiResponse.success("成功封禁 " + successCount + " 个用户");
        } else {
            return ApiResponse.success("成功封禁 " + successCount + " 个用户，失败 " + 
                                    failCount + " 个。失败原因：" + failureMessage.toString());
        }
    }

    @Override
    @Transactional
    public ApiResponse<?> batchUnbanUsers(List<Long> userIds) {
        if (userIds == null || userIds.isEmpty()) {
            return ApiResponse.error("用户ID列表不能为空");
        }

        int successCount = 0;
        int failCount = 0;
        StringBuilder failureMessage = new StringBuilder();

        for (Long userId : userIds) {
            try {
                ApiResponse<?> response = unbanUser(userId);
                if (response.isSuccess()) {
                    successCount++;
                } else {
                    failCount++;
                    failureMessage.append("用户ID ").append(userId).append(": ")
                                .append(response.getMessage()).append("; ");
                }
            } catch (Exception e) {
                failCount++;
                failureMessage.append("用户ID ").append(userId).append(": ")
                            .append(e.getMessage()).append("; ");
            }
        }

        if (failCount == 0) {
            return ApiResponse.success("成功解封 " + successCount + " 个用户");
        } else {
            return ApiResponse.success("成功解封 " + successCount + " 个用户，失败 " + 
                                    failCount + " 个。失败原因：" + failureMessage.toString());
        }
    }
}